package com.wang.common.annotation.aop;

import com.wang.common.annotation.Log;
import com.wang.common.common.AResponse;
import com.wang.common.common.ErrorCode;
import com.wang.common.exception.BusinessException;
import com.wang.common.model.DaOpeLog;
import com.wang.common.model.RUser;
import com.wang.common.service.DaOpeLogService;
import com.wang.common.utils.RedisUtil;
import com.wang.common.utils.ResultUtils;
import com.wang.common.utils.Utils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * 操作日志aop
 *
 * @since 2022.11.02
 */
@Aspect
@Component
@Slf4j
public class LogAop {

    @Resource
    private DaOpeLogService daOpeLogService;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    HttpServletRequest request;

    @Pointcut("@annotation(com.wang.common.annotation.Log)")
    public void log() {
    }

//    @Before("log()")
//    public void beforeAdvice(JoinPoint jp) {
//        // 获取操作员ID
//        String userId = "0";
//        String token = request.getHeader("token");
//        // 获取Redis中存放的用户信息
//        RUser userInfo = null;
//        if (Utils.isNotEmpty(token)) {
//             userInfo = (RUser) Utils.jsonStringToObj(redisUtil.getString(token), RUser.class);
//        }
//        if (userInfo != null) {
//            userId = userInfo.getUserid();
//        }
//        userId = userId != null ? userId : "0";
//
//        DaOpeLog daOpeLog = new DaOpeLog();
//        MethodSignature signature = (MethodSignature) jp.getSignature();
//        Log annotation = signature.getMethod().getAnnotation(Log.class);
//        daOpeLog.setLogid(Utils.genRanNo());
//        daOpeLog.setClazz(annotation.clazz());
//        daOpeLog.setMethod(annotation.method());
//        daOpeLog.setLevelid(annotation.level());
//        daOpeLog.setCreatetime(Utils.convertDateToString());
//        daOpeLog.setUserid(userId);
//        this.daOpeLog = daOpeLog;
//    }
//
//    @AfterReturning(pointcut = "log()", returning = "ret")
//    public void afterReturningAdvice(JoinPoint jp, Object ret) {
//        AResponse result = (AResponse) ret;
//        saveLog(result.getMessage());
//    }
//
//    @AfterThrowing(pointcut = "log()", throwing = "ret")
//    public void afterThrowingAdvice(Throwable ret) {
//        try {
//            BusinessException thr = (BusinessException) ret;
//            saveLog(thr.getDescription());
//        } catch (Exception e) {
//            saveLog(e.getMessage());
//        }
//    }

    @Around("log()")
    public Object aroundAdvice(ProceedingJoinPoint pjp) {
        AResponse<?> result = null;
        BusinessException bx = null;
        Throwable exception = null;
        // 获取操作员ID
        String userId = "0";
        String token = request.getHeader("token");
        // 获取Redis中存放的用户信息
        RUser userInfo = null;
        if (Utils.isNotEmpty(token)) {
            userInfo = (RUser) Utils.jsonStringToObj(redisUtil.getString(token), RUser.class);
        }
        if (userInfo != null) {
            userId = userInfo.getUserid();
        }
        userId = userId != null ? userId : "0";

        DaOpeLog daOpeLog = new DaOpeLog();
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Log annotation = signature.getMethod().getAnnotation(Log.class);
        daOpeLog.setLogid(Utils.genRanNo());
        daOpeLog.setClazz(annotation.clazz());
        daOpeLog.setMethod(annotation.method());
        daOpeLog.setLevelid(annotation.level());
        daOpeLog.setCreatetime(Utils.convertDateToString());
        daOpeLog.setUserid(userId);
        try {
            result = (AResponse<?>) pjp.proceed();
        } catch (BusinessException businessException) {
            bx = businessException;
            log.error(bx.getMessage(), bx);
        } catch (Throwable throwable) {
            exception = throwable;
            log.error(throwable.getMessage(), throwable);
        }
        if ("0".equals(daOpeLog.getUserid()) && Utils.isNotEmpty((String) request.getAttribute("userId"))) {
            daOpeLog.setUserid((String) request.getAttribute("userId"));
        }
        if (result != null && result.getMessage() != null) {
            daOpeLog.setRemark(result.getMessage());
        } else if (bx != null) {
            daOpeLog.setRemark(bx.getMessage());
        } else if (exception != null) {
            daOpeLog.setRemark(exception.getMessage());
        }

        if (daOpeLog.getRemark() == null && exception != null) {
            daOpeLog.setRemark(exception.toString());
        }

        try {
            // 插入日志
            daOpeLogService.save(daOpeLog);
        } catch (Exception e) {
            log.error("日志插入失败！", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "日志插入异常");
        }
        if (result != null) {
            return result;
        } else if (bx != null) {
            return ResultUtils.error(bx.getCode(), bx.getMessage(), bx.getDescription());
        } else if (exception != null) {
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, exception.getMessage() == null ? exception.toString() : exception.getMessage());
        }
        return null;
    }

//    private void saveLog(String message) {
//        if ("0".equals(daOpeLog.getUserid()) && Utils.isNotEmpty((String) request.getAttribute("userId"))) {
//            daOpeLog.setUserid((String) request.getAttribute("userId"));
//        }
//        daOpeLog.setRemark(message);
//
//        try {
//            // 插入日志
//            daOpeLogService.save(daOpeLog);
//        } catch (Exception e) {
//            log.error("日志插入失败！", e);
//            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "日志插入异常");
//        }
//    }
}
